import {forwardRef, HttpException, HttpStatus, Inject, Injectable} from '@nestjs/common';
import {InjectRepository} from '@nestjs/typeorm';
import {UserEntity} from './entities/user.entity';
import {Repository} from 'typeorm';
import { handleCurTime, handleFilterObjectEmptyData, handleReplaceSpecialChar, securityMd5 } from "@/utils/utils";
import {AuthService} from '../auth/auth.service';
import {UserAddDto, UserListDto, UserUpdateDto} from "./dto";
import {MsgService} from "@/modules/common/msg/msg.service";
import {RoleEntity} from "@/modules/role/entities/role.entity";
import {SysConfigEntity} from "@/modules/sysConfig/entities/sysConfig.entity";
import {ImgEntity} from "@/modules/img/entities/img.entity";
import { MenuEntity } from '@/modules/menu/entities/menu.entity';


@Injectable()
export class UserService {
  constructor(
      //依赖注入
      @InjectRepository(UserEntity) private readonly userEntity:Repository<UserEntity>,
      @InjectRepository(RoleEntity) private readonly roleEntity:Repository<RoleEntity>,
      @InjectRepository(SysConfigEntity) private readonly sysConfigEntity:Repository<SysConfigEntity>,
      @InjectRepository(ImgEntity) private readonly imgEntity:Repository<ImgEntity>,
      @InjectRepository(MenuEntity) private readonly menuEntity:Repository<MenuEntity>,
      @Inject(forwardRef(() => AuthService)) private readonly authService:AuthService,
      private readonly msgService:MsgService
  ) {}

  /**
   * 用户列表
   * @param userListDto
   */
  async userList(userListDto:UserListDto) {
    let {pageSize,currentPage} = userListDto
    let filterData = handleFilterObjectEmptyData(userListDto);
    let startNum = pageSize*(currentPage-1)
    let userTotal;
    try {
      userTotal = await this.userEntity.createQueryBuilder().where({...filterData}).getCount()
    }catch (error) {
      return this.msgService.fail(error);
    }
    let user;
    try {
      user = await this.userEntity.createQueryBuilder().where({...filterData}).skip(startNum).take(pageSize).getMany()
      if(user.length>0){
        let roleList = await this.roleEntity.createQueryBuilder().select(["id","roleName"]).getRawMany();
        for(let i in user){
          for(let q in roleList){
            if(user[i]["roleId"] == roleList[q]["id"]){
              user[i]["roleName"] = roleList[i]["roleName"]??"";
            }
          }
          if(user[i]["headImgId"]>0 && user[i]["headImgId"]){
            let img = await this.imgEntity.createQueryBuilder().select(["imgMidUrl"]).where("id = :id",{id:user[i]["headImgId"]}).getRawOne();
            user[i]["headImg"] = img["imgMidUrl"]
          }else{
            user[i]["headImg"] = ""
          }
        }
      }

    }catch (error) {
      return this.msgService.fail(error);
    }
    return this.msgService.success({total:userTotal,data:user});
  }

  /**
   * 添加用户
   * @param userAddDto
   */
  async userAdd(userAddDto: UserAddDto) {
    let {nickName,username,password} = userAddDto
    if(!nickName){
      userAddDto.nickName = username
    }
    let filterData = handleFilterObjectEmptyData(userAddDto);
    const num = await this.userEntity.createQueryBuilder().where({username}).getCount()
    if(num>0){
      return this.msgService.fail("用户名重复", 404);
    }
    let originalPwd = JSON.parse(JSON.stringify(password))
    password = securityMd5(password)
    try {
      await this.userEntity.createQueryBuilder().insert().values({...filterData,originalPwd,password}).execute();
    }catch (error) {
      throw new HttpException(error,HttpStatus.SERVICE_UNAVAILABLE)
    }
    return this.msgService.success()
  }

  /**
   * 编辑用户
   * @param userUpdateDto
   */
  async userUpdate(userUpdateDto:UserUpdateDto) {
    let {id,password,originalPwd} = userUpdateDto
    let filterData = handleFilterObjectEmptyData(userUpdateDto);
    let updateTime = handleCurTime();
    password = JSON.parse(JSON.stringify(originalPwd))
    password = securityMd5(password)
    try {
      await this.userEntity.createQueryBuilder().where("id = :id", { id }).update().set({...filterData,updateTime,originalPwd,password}).execute();
    }catch (error) {
      return this.msgService.fail(error);
    }
    return this.msgService.success();
  }

  /**
   * 删除
   * @param id
   */
  async delete(id: string) {
    let ids = id.split(",")
    try {
      await this.userEntity.createQueryBuilder().delete().where("id in (:id)",{id:[...ids]}).execute()
    }catch (error){
      return this.msgService.fail(error);
    }
    return this.msgService.success();
  }

  /**
   * 通过用户名查找用户详情
   * @param username
   */
  async userDetailByUserName(username:string):Promise<UserEntity>{
    return await this.userEntity.createQueryBuilder().where({username}).getOne()
  }

  /**
   * 通过用户id查找用户详情
   * @param id
   */
  async userDetailByUserId(id:number):Promise<UserEntity | undefined>{
    let userDetail  =  await this.userEntity.createQueryBuilder().select(["*"]).where({id}).getRawOne();
    if(userDetail["headImgId"]>0 && userDetail["headImgId"]){
      let img = await this.imgEntity.createQueryBuilder().select(["imgMidUrl"]).where("id = :id",{id:userDetail["headImgId"]}).getRawOne();
      userDetail["headImg"] = img["imgMidUrl"]
    }else{
      userDetail["headImg"] = ""
    }
    if(userDetail["roleId"]>0 && userDetail["roleId"]){
      let img = await this.roleEntity.createQueryBuilder().select(["roleName"]).where("id = :id",{id:userDetail["roleId"]}).getRawOne();
      userDetail["roleName"] = img["roleName"]
    }else{
      userDetail["roleName"] = ""
    }
    return userDetail
  }

  /**
   * 通过用户id查找用户详情
   * @param username
   * @param password
   */
  async userDetailByUsernameAndPwd(username:string,password:string):Promise<UserEntity | undefined>{
    let originalPwd = password
    password = securityMd5(password)
    return await this.userEntity.createQueryBuilder().where({username, password, originalPwd}).getOne()
  }

  /**
   * 登录passport-jwt
   * @param user
   */
  async login(user:{username:string,password:string}){
    //加锁
    //https://www.bookstack.cn/read/TypeORM-0.2.20-zh/spilt.21.select-query-builder.md
    // let test = await getRepository(UserEntity).createQueryBuilder("user").setLock("pessimistic_read").getMany();
    let {username,password} = user
    username = handleReplaceSpecialChar(username)
    password = handleReplaceSpecialChar(password)
    let userData;
    try {
      userData = await this.userDetailByUsernameAndPwd(username,password)
    } catch (error) {
      return this.msgService.fail(error)
    }
    if(userData["status"]!=1){
      return this.msgService.fail("该账号已被停用，请联系管理员")
    }
    if(userData){
      let {id,username} = userData;
      let token = this.authService.createToken({id,username})
      return {
        id,username,token
      }
    }else{
      return this.msgService.fail("账号密码不匹配",HttpStatus.UNAUTHORIZED)
    }
  }
  /**
   * 解码token获取用户id和username
   * @param token
   */
  async userInfo(token:string){
    let tokenData = await this.authService.verifyToken(token)
    let curTime = handleCurTime()
    //过期
    if(tokenData.exp*1000 <= curTime){
      throw new HttpException('token已过期', HttpStatus.BAD_GATEWAY);
    }
    let uid = tokenData.id;
    let data = {
      "userInfo": {},//用户信息
      "permissions": [],//权限
      "roles": [],//角色
      "sysConfig": [],//系统配置
    }
    //用户详细信息
    let userData = await this.userEntity.createQueryBuilder().where({id:uid}).getOne()
    let roleId = userData?.roleId;
    let roleData = await this.roleEntity.createQueryBuilder().where({id:roleId}).getOne()
    data.userInfo = {
      id:userData.id,
      username:userData.username,
      roleName:roleData.roleName??"",
      email:userData.email,
      sex:userData.sex,
      phone:userData.phone,
    }
    //权限字符
    let permissions = [];
    if(roleData?.perms=="admin"){
      permissions.push("*:*:*")
    }else{
      if(roleData?.menuIds.split(",").length>0){
        let menuIdArr = roleData?.menuIds.split(",")
        for(let i in menuIdArr){
          let menuData = await this.menuEntity.createQueryBuilder().where({id:menuIdArr[i]}).getOne()
          if(menuData){
            permissions.push(menuData["perms"])
          }
        }
      }
      permissions = permissions.filter((item)=>{
        return item && item;
      })
    }
    data.permissions = permissions
    //用户角色
    data.roles = [`${roleData?.perms}`]

    data.sysConfig = await this.sysConfigDetail()

    return await this.msgService.success(data)
  }

  /**
   * 系统配置
   */
  async sysConfigDetail(){
   let sysConfig =  await this.sysConfigEntity.createQueryBuilder("sysConfig").select(["value"]).where("sysConfig.key = :key",{key:"BASE_SETTING"}).getRawOne()
    return sysConfig["value"] && JSON.parse(sysConfig["value"])
  }

  /**
   * 修改用户状态
   * @param id
   * @param status
   */
  async userChangeStatus(id:number,status: number|string) {
    let updateTime = handleCurTime();
    try {
      await this.userEntity.createQueryBuilder().where("id = :id", { id }).update().set({status,updateTime}).execute();
    }catch (error){
      return this.msgService.fail(error);
    }
    return this.msgService.success();
  }
}
